package com.log.administrator;

import com.log.resolver.DefaultLogBody;
import com.log.resolver.DefaultLogDescribe;
import com.log.resolver.interfaces.LogBody;
import com.log.resolver.interfaces.LogDescribe;
import com.log.unit.LogContext;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName LogParamManage
 * @Author xiezhuocai
 * @Description TODO
 * @Date 2022/5/11 20:45
 */
public class LogParamManage implements LogManage {

    private LocalVariableTableParameterNameDiscoverer discoverer;

    private LogBody logBody;

    private LogDescribe logDescribe;

    private LogContext logContext;

    public LogParamManage(String target,String stock,String mSpEL,String fun){
        this(target,stock,mSpEL,fun,new LocalVariableTableParameterNameDiscoverer(),new DefaultLogBody(target),new DefaultLogDescribe(stock,mSpEL,fun));
    }

    public LogParamManage(String target,String stock,String mSpEL,String fun,
                          LocalVariableTableParameterNameDiscoverer discoverer,LogBody logBody,LogDescribe logDescribe){
        this.logContext = new LogContext(target,stock,mSpEL,fun);
        this.discoverer = discoverer;
        this.logBody = logBody;
        this.logDescribe = logDescribe;
        logContext.setStockKey(logDescribe.stockKey());
        logContext.setmSpELKey(logDescribe.mSpELKey());
        logContext.setFunKey(logDescribe.funKey());
        logContext.setBodyKey(logBody.section());
    }


    @Override
    public Map<String,String> spELFun(Map<String,String> logValue, Object rootObject, Method method, Object[] args){
        Map<String,String> result = new HashMap<>();
        EvaluationContext context = new MethodBasedEvaluationContext(rootObject,method,args,discoverer);
        //ParserContext context = new TemplateParserContext();
        SpelExpressionParser parser = new SpelExpressionParser();
        logValue.forEach((k,v)->{
            Expression expression = parser.parseExpression(v);
            String value = expression.getValue(context, Object.class).toString();
            result.put(k,value);
        });
        return result;
    }


    @Override
    public LogContext getLogContext() {
        return logContext;
    }

    @Override
    public LogBody getLogBody() {
        return logBody;
    }

    @Override
    public LogDescribe getLogDescribe() {
        return logDescribe;
    }
}
